using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

public class TrayIconApp : Form
{
    private class WindowInfo
    {
        public IntPtr Handle { get; set; }
        public string WindowTitle { get; set; }
        public string ExeName { get; set; }
        
        public string DisplayName => string.IsNullOrEmpty(WindowTitle) ? ExeName : WindowTitle;
    }
    
    private NotifyIcon trayIcon;
    private ContextMenuStrip trayMenu;
    private Label mainLabel;
    private Label copyrightLabel;
    private System.Windows.Forms.Timer autoHideTimer;
    private List<WindowInfo> topWindows = new List<WindowInfo>();
    private ToolStripMenuItem showMainMenuItem;
    private ToolStripMenuItem unpinAllMenuItem;
    private ToolStripSeparator separator1;
    private ToolStripMenuItem noTopWindowsMenuItem;
    private ToolStripSeparator separator2;
    private ToolStripMenuItem exitMenuItem;
    private System.Windows.Forms.Timer tooltipDelayTimer;

    public TrayIconApp()
    {
        // 设置窗体属性
        this.Text = "窗口置顶工具";
        this.Size = new Size(600, 200);
        this.FormBorderStyle = FormBorderStyle.FixedSingle; // 固定大小，不可调整
        this.MaximizeBox = false; // 禁用最大化按钮
        this.StartPosition = FormStartPosition.CenterScreen; // 在屏幕中央启动

        // 创建主要文本标签
        mainLabel = new Label();
        mainLabel.Text = "窗口置顶工具\n选中窗体，按下Ctrl+Alt+Shift+D置顶或取消置顶窗体\n©Copyright2025 EmmmQaQ";
        mainLabel.AutoSize = false;
        mainLabel.TextAlign = ContentAlignment.MiddleCenter;
        mainLabel.Dock = DockStyle.Fill;
        mainLabel.Font = new Font(mainLabel.Font.FontFamily, 14, FontStyle.Bold);
        this.Controls.Add(mainLabel);

        // 创建版权信息标签
        copyrightLabel = new Label();
        copyrightLabel.Text = "©Copyright2025 EmmmQaQ";
        copyrightLabel.AutoSize = true;
        copyrightLabel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
        this.Controls.Add(copyrightLabel);

        // 调整版权标签位置
        this.Resize += (sender, e) => AdjustCopyrightPosition();
        AdjustCopyrightPosition();

        // 创建托盘图标和菜单
        trayMenu = new ContextMenuStrip();
        InitializeTrayMenu();
        trayMenu.Opening += OnTrayMenuOpening;
        
        trayIcon = new NotifyIcon();
        trayIcon.Text = "窗口置顶工具";
        trayIcon.Icon = SystemIcons.Application;
        trayIcon.ContextMenuStrip = trayMenu;
        trayIcon.Visible = true;
        trayIcon.Click += OnTrayIconClick;

        // 注册全局热键
        RegisterHotKey(this.Handle, 1, 0x0002 | 0x0001 | 0x0004, (int)Keys.D);

        // 处理窗体事件
        this.Resize += OnFormResize;
        
        // 创建自动隐藏计时器
        autoHideTimer = new System.Windows.Forms.Timer();
        autoHideTimer.Interval = 3000; // 3秒
        autoHideTimer.Tick += AutoHideTimer_Tick;
        autoHideTimer.Start();
        
        // 创建ToolTip延迟计时器
        tooltipDelayTimer = new System.Windows.Forms.Timer();
        tooltipDelayTimer.Interval = 800; // 800毫秒延迟
        tooltipDelayTimer.Tick += TooltipDelayTimer_Tick;
    }
    
    private void AutoHideTimer_Tick(object sender, EventArgs e)
    {
        autoHideTimer.Stop(); // 停止计时器
        this.Hide(); // 隐藏窗口
        trayIcon.Visible = true; // 确保托盘图标可见
    }
    
    private void TooltipDelayTimer_Tick(object sender, EventArgs e)
    {
        tooltipDelayTimer.Stop();
    }

    private void AdjustCopyrightPosition()
    {
        copyrightLabel.Location = new Point(
            this.ClientSize.Width - copyrightLabel.Width - 10,
            this.ClientSize.Height - copyrightLabel.Height - 10);
    }

    private void InitializeTrayMenu()
    {
        // 预创建固定菜单项，避免每次Opening时重新创建
        showMainMenuItem = new ToolStripMenuItem("显示主界面", null, (EventHandler)OnShow);
        unpinAllMenuItem = new ToolStripMenuItem("取消所有置顶", null, (EventHandler)UnpinAllWindows);
        separator1 = new ToolStripSeparator();
        noTopWindowsMenuItem = new ToolStripMenuItem("单击选中项取消置顶", null, (EventHandler)null) { Enabled = false };
        separator2 = new ToolStripSeparator();
        exitMenuItem = new ToolStripMenuItem("退出", null, (EventHandler)OnExit);
        
        trayMenu.Items.AddRange(new ToolStripItem[] 
        {
            showMainMenuItem,
            unpinAllMenuItem,
            separator1,
            noTopWindowsMenuItem,
            separator2,
            exitMenuItem
        });
    }

    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        // 点击关闭按钮时退出程序
        if (e.CloseReason == CloseReason.UserClosing)
        {
            trayIcon.Visible = false;
            Application.Exit();
        }
        else
        {
            base.OnFormClosing(e);
        }
    }

    private void OnFormResize(object sender, EventArgs e)
    {
        if (this.WindowState == FormWindowState.Minimized)
        {
            this.Hide();
            trayIcon.Visible = true;
        }
    }

    private void OnTrayIconClick(object sender, EventArgs e)
    {
        if (e is MouseEventArgs mouseEvent && mouseEvent.Button == MouseButtons.Left)
        {
            Show();
            this.WindowState = FormWindowState.Normal;
        }
    }

    private void OnShow(object sender, EventArgs e)
    {
        Show();
        this.WindowState = FormWindowState.Normal;
    }

    private void OnTrayMenuOpening(object sender, System.ComponentModel.CancelEventArgs e)
    {
        // 清除动态添加的窗口菜单项（从separator1之后到separator2之前）
        int startIndex = trayMenu.Items.IndexOf(separator1) + 1;
        int endIndex = trayMenu.Items.IndexOf(separator2);
        
        // 倒序删除动态菜单项，避免索引变化
        for (int i = endIndex - 1; i >= startIndex; i--)
        {
            if (trayMenu.Items[i] != noTopWindowsMenuItem)
            {
                trayMenu.Items.RemoveAt(i);
            }
        }
        
        // 根据置顶窗口数量更新菜单
        if (topWindows.Count == 0)
        {
            // 显示"无置顶窗口"提示
            if (!trayMenu.Items.Contains(noTopWindowsMenuItem))
            {
                int insertIndex = trayMenu.Items.IndexOf(separator2);
                trayMenu.Items.Insert(insertIndex, noTopWindowsMenuItem);
            }
            noTopWindowsMenuItem.Text = "无置顶窗口";
            noTopWindowsMenuItem.Enabled = false;
        }
        else
        {
            noTopWindowsMenuItem.Text = "左击激活窗口，右击取消置顶";
            /*
            // 隐藏"无置顶窗口"提示
            if (trayMenu.Items.Contains(noTopWindowsMenuItem))
            {
                trayMenu.Items.Remove(noTopWindowsMenuItem);
            }
            */
            
            // 添加置顶窗口列表
            int insertIndex = trayMenu.Items.IndexOf(separator2);
            foreach (var window in topWindows)
            {
                string displayText = window.DisplayName.Length > 30 ? 
                    window.DisplayName.Substring(0, 30) + ".." : 
                    window.DisplayName;
                var menuItem = new ToolStripMenuItem(displayText, null, (s, args) => ActivateWindow(window.Handle));
                // 保存窗口句柄到Tag中，以便右键事件使用
                menuItem.Tag = window.Handle;
                // 只有在窗口名被截断时才设置ToolTip
                if (window.DisplayName.Length > 30)
                {
                    menuItem.ToolTipText = window.DisplayName;
                }
                // 添加鼠标事件处理
                menuItem.MouseDown += OnWindowMenuItemMouseDown;
                trayMenu.Items.Insert(insertIndex, menuItem);
                insertIndex++;
            }
        }
    }
    
    private void OnExit(object sender, EventArgs e)
    {
        UnpinAllWindows(sender, e);
        trayIcon.Visible = false;
        Application.Exit();
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0312 && m.WParam.ToInt32() == 1)
        {
            IntPtr hWnd = GetForegroundWindow();
            ToggleTopMost(hWnd);
        }
        base.WndProc(ref m);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            trayIcon.Dispose();
            UnregisterHotKey(this.Handle, 1);
            autoHideTimer.Dispose(); // 释放计时器资源
            tooltipDelayTimer.Dispose(); // 释放ToolTip计时器资源
        }
        base.Dispose(disposing);
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new TrayIconApp());
    }

    // 以下是之前定义的 P/Invoke 方法和相关结构体
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
    
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern uint GetWindowModuleFileName(IntPtr hWnd, StringBuilder lpString, uint nMaxCount);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
    static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, int vk);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    private const int SW_RESTORE = 9;

    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct WINDOWINFO
    {
        public uint cbSize;
        public RECT rcWindow;
        public RECT rcClient;
        public uint dwStyle;
        public uint dwExStyle;
        public uint dwWindowStatus;
        public uint cxWindowBorders;
        public uint cyWindowBorders;
        public ushort atomWindowType;
        public ushort wCreatorVersion;

        public WINDOWINFO(Boolean? filler) : this()
        {
            cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(WINDOWINFO));
        }
    }

    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left, Top, Right, Bottom;
    }

    private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
    private static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
    private const uint SWP_NOMOVE = 0x0002;
    private const uint SWP_NOSIZE = 0x0001;
    private const uint WS_EX_TOPMOST = 0x00000008;

    private string GetWindowDisplayName(IntPtr hWnd)
    {
        StringBuilder windowTitle = new StringBuilder(256);
        GetWindowText(hWnd, windowTitle, 256);
        
        if (!string.IsNullOrEmpty(windowTitle.ToString()))
        {
            return windowTitle.ToString();
        }
        
        StringBuilder moduleFileName = new StringBuilder(256);
        GetWindowModuleFileName(hWnd, moduleFileName, 256);
        
        if (!string.IsNullOrEmpty(moduleFileName.ToString()))
        {
            return Path.GetFileName(moduleFileName.ToString());
        }
        
        return "未知窗口";
    }
    
    private string GetWindowExeName(IntPtr hWnd)
    {
        StringBuilder moduleFileName = new StringBuilder(256);
        GetWindowModuleFileName(hWnd, moduleFileName, 256);
        
        if (!string.IsNullOrEmpty(moduleFileName.ToString()))
        {
            return Path.GetFileName(moduleFileName.ToString());
        }
        
        return "未知程序";
    }
    
    private void AddToTopList(IntPtr hWnd)
    {
        if (!topWindows.Exists(w => w.Handle == hWnd))
        {
            // 缓存窗口信息，避免菜单打开时重复获取
            var windowInfo = new WindowInfo
            {
                Handle = hWnd,
                WindowTitle = GetWindowDisplayName(hWnd),
                ExeName = GetWindowExeName(hWnd)
            };
            topWindows.Add(windowInfo);
        }
    }
    
    private void OnWindowMenuItemMouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            var menuItem = sender as ToolStripMenuItem;
            if (menuItem != null && menuItem.Tag is IntPtr hWnd)
            {
                // 右键点击：取消置顶
                RemoveFromTopList(hWnd);
                // 关闭菜单
                trayMenu.Close();
            }
        }
    }

    private void ActivateWindow(IntPtr hWnd)
    {
        // 如果窗口被最小化，先恢复
        ShowWindow(hWnd, SW_RESTORE);
        // 激活窗口并获得焦点
        SetForegroundWindow(hWnd);
    }

    private void RemoveFromTopList(IntPtr hWnd)
    {
        var window = topWindows.Find(w => w.Handle == hWnd);
        if (window != null)
        {
            topWindows.Remove(window);
            SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
        }
    }
    
    private void UnpinAllWindows(object sender, EventArgs e)
    {
        foreach (var window in topWindows.ToArray())
        {
            SetWindowPos(window.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
        }
        topWindows.Clear();
    }

    private void ToggleTopMost(IntPtr hWnd)
    {
        WINDOWINFO info = new WINDOWINFO(true);
        GetWindowInfo(hWnd, ref info);

        if ((info.dwExStyle & WS_EX_TOPMOST) != 0)
        {
            // 窗口当前是置顶的，取消置顶
            SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
            RemoveFromTopList(hWnd);
        }
        else
        {
            // 窗口当前不是置顶的，设置为置顶
            SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
            AddToTopList(hWnd);
        }
    }
}
